﻿#include "CameraNetWork.h"
#ifdef Q_OS_WIN
#include <Windows.h>
#else
#include <unistd.h>
#endif
//#include "logger.h"
#include <QDebug>


CameraNetWork::CameraNetWork(const std::string name):
    Camera(name)
  ,m_cap(nullptr)
  //,m_expose(100)
  ,m_capIndex(0)
{
    m_reconnect_max = 1;
}

CameraNetWork::~CameraNetWork()
{

}


//void CameraNetWork::onSaveParam(int exposeVal, int camerCapNum)
//{
//   qDebug()<<"CameraNetWork::onSaveParam exposeVal="<<exposeVal<<" camerCapNum="<<camerCapNum<<"\n";
//   if(m_capIndex != camerCapNum)
//   {
//        m_capIndex = camerCapNum;
//        if(m_cap){
//            delete m_cap;
//        }
//        this->initialize();
//        this->openCamera();
//        //this->setTriggerSinglePicture(true);
//   }

//   if(m_cap && m_expose != exposeVal)
//   {
//      m_expose = exposeVal;
//      m_cap->set(cv::CAP_PROP_EXPOSURE, m_expose); // 设置曝光值
//   }
//}

void CameraNetWork::initialize()
{
    QMutexLocker mutexLocker(&m_lock);
    setStatus(Unavailable);

    int index = 0;
    int nPos = m_name.find_first_not_of("Camera");
    if(nPos != -1){
        std::string camera_index = m_name.substr(nPos, m_name.length() - nPos);
        index = atoi(camera_index.c_str());
    }

    //m_index = index;
    if(index > 0 )
        index -=1;

    m_cap = new cv::VideoCapture(index);

    //m_status = Closed;
    //m_triggerSource = -1;
    //m_singlePic = false;
    setStatus(Closed);
    emitMessage(tr(u8"<font color=\'green\'>相机初始化</font>"));
}

void CameraNetWork::openCamera()
{
    // Open device
    if(!m_cap->isOpened()){
        setStatus(Unavailable);
        printf("Open Device failed!\n");
        emitMessage(tr(u8"<font color=\'red\'>相机打开失败\n</font>"));
    } else {
        setStatus(Opened);
        printf("Open Device succeed!\n");
        emitMessage(tr(u8"<font color=\'green\'>相机打开成功</font>"));

//        m_cap->set(cv::CAP_PROP_FRAME_WIDTH, 1920);
//        m_cap->set(cv::CAP_PROP_FRAME_HEIGHT, 892);
        m_cap->set(cv::CAP_PROP_FPS, 20);

        m_cap->set(cv::CAP_PROP_FRAME_WIDTH, m_width);
        m_cap->set(cv::CAP_PROP_FRAME_HEIGHT, m_height);
        m_cap->set(cv::CAP_PROP_FOURCC,  cv::VideoWriter::fourcc('M', 'J', 'P', 'G'));
        m_cap->set(cv::CAP_PROP_AUTO_EXPOSURE, 1); // 关闭自动曝光模式
        //m_cap->set(cv::CAP_PROP_EXPOSURE, m_expose); // 设置曝光值为 -5
    }


    if(m_status == Opened){
        m_worker = new CameraWorker();
        m_thread = new QThread();
        m_worker->init(m_cap);

        m_worker->moveToThread(m_thread);

        connect(this, &CameraNetWork::sigStart, m_worker, &CameraWorker::run);
        connect(m_worker, &QObject::destroyed, m_thread, &QThread::quit);
        connect(m_thread, &QThread::finished, m_worker, &QObject::deleteLater);
        connect(m_worker, &CameraWorker::sigCaptureFinished, this, &CameraNetWork::onCaptureFinished);
        connect(m_worker, &CameraWorker::sigWarning, this, &CameraNetWork::onWarnMessg);

        m_thread->start();

#ifdef Q_OS_WIN
        _sleep(2);
#else
        sleep(2);
#endif
        emit sigStart();

    }

    //m_reconnect_cnt = 0;
    m_takePic = false;
}

void CameraNetWork::onWarnMessg(QString messg)
{
    emit cameraWarning(m_name, messg);
}
void CameraNetWork::startGrabbing()
{
    if(m_status == Opened){
        emitMessage(tr(u8"<font color=\'green\'>相机采集</font>"));
        setStatus(Grabbing);
    }
}

void CameraNetWork::stopGrabbing()
{
    // Stop grab image
    if(m_status == Grabbing){
        emitMessage(tr(u8"相机打开"));
        setStatus(Opened);
    }
}


void CameraNetWork::closeCamera()
{
    if(m_status == Opened){
        setStatus(Closing);

        emitMessage(tr(u8"相机关闭"));
        setStatus(Closed);
    }
}

void CameraNetWork::releaseCamera()
{
    m_cap->release();
    setStatus(Unavailable);
}


void CameraNetWork::onCaptureFinished(cv::Mat frame){
     //取单帧
    if(m_takePic){
         m_takePic = false;
         emit sendCVImage(m_name, frame);
    }
}


void CameraNetWork::preProcessImage(const ImageInfo &imgInfo)
{

}

bool CameraNetWork::isColor(int pixelFormat)
{

    return false;
}

bool CameraNetWork::isMono(int pixelFormat)
{

    return  false;
}


void CameraNetWork::triggerSoftware()
{
    m_takePic = true;
}

void CameraNetWork::setExposureTime(const std::string &camName, const FloatValue &value)
{
    if(camName!=m_name)
        return;

    if(m_cap )
    {
       auto m_expose = value.fCurValue;
       m_cap->set(cv::CAP_PROP_EXPOSURE, m_expose); // 设置曝光值
       m_expose = m_cap->get(cv::CAP_PROP_EXPOSURE);
       qDebug()<<QString::fromStdString(camName) <<" exposeVal="<<m_expose<<"\n";
    }
}

void CameraNetWork::setBrightness(const std::string &camName, const FloatValue &value)
{
    if(camName!=m_name)
        return;

    if(m_cap )
    {
       auto brightness = value.fCurValue;
       m_cap->set(cv::CAP_PROP_BRIGHTNESS, brightness); // 设置亮度值
       brightness = m_cap->get(cv::CAP_PROP_BRIGHTNESS);
       qDebug()<<QString::fromStdString(camName) <<" brightness="<<brightness<<"\n";
    }
}


void CameraNetWork::setWidth(const std::string &camName, const IntValue &width)
{
    if(camName!=m_name)
        return;
    m_width = width.nCurValue;
//    if(m_cap){
//        //bool b = m_cap->set(cv::CAP_PROP_FRAME_WIDTH, 640);
//        bool b2 = m_cap->set(cv::CAP_PROP_FRAME_HEIGHT, 480);
//        //printf(" CAP_PROP_FRAME_WIDTH %d\n",b);
//       // printf(" CAP_PROP_FRAME_HEIGHT %d\n",b2);
//    }
//       printf("+++++++++++++++++++\n");
}

void CameraNetWork::setHeight(const std::string &camName, const IntValue &height)
{
    if(camName!=m_name)
        return;
    m_height = height.nCurValue;
}

CameraWorker::CameraWorker(QObject *parent) :QObject(parent)
{

}

void CameraWorker::init(void* cap)
{
    m_cap = (cv::VideoCapture*)cap;
}


void CameraWorker::run()
{
    while (1) {
        cv::Mat frame;
        if(!m_cap->read(frame)){
            emit sigWarning(tr(u8"<font color=\'red\'>相机离线\n</font>"));
            break;
        }

        if(!frame.empty()){
            emit sigCaptureFinished(frame.clone());
        }
    }
}
